コンピュータシステムの世界では、 アプリケーションレベルの並行処理 論理的な制御フローを意図的に重ね合わせることで、パフォーマンスと応答性を向上させる。これは機能的な抽象化であり、プログラムが独立したタスクに分割され、順序を入れ替えたり、並列に実行できるようにする。
1. 並行処理の分類
開発者は、これらの並行処理を管理するために、一般的に3つの基本的なメカニズムのうちいずれかを選択する。
- プロセス: 個別の仮想アドレス空間を持つ高い分離性;カーネルによる中継が必要なIPC(プロセス間通信)を要する。
- I/Oマルチプレクシング: 単一のフローが「準備完了」イベントの間を手動で切り替える(状態機械)。
- スレッド: データ交換が容易な単一の仮想アドレス空間を共有する軽量なフロー。
2. 論理的実行と物理的実行の違い
すべての 並列プログラム 並列プログラムはすべて並行処理であるが、すべての並行処理プログラムが並列であるわけではない。並列性とは、別々のハードウェアコア上でフローを物理的に実行することである。並行処理は、そのような実行が可能になるように設計された論理的な構造である。
main.py
TERMINALbash — 80x24
> Ready. Click "Run" to execute.
>
QUESTION 1
Which concurrency model offers the highest level of isolation between flows?
Threads
I/O Multiplexing
Processes
Coroutines
✅ Correct!
Processes have separate virtual address spaces, making them highly isolated but requiring IPC for communication.❌ Incorrect
Threads share the same address space, and I/O multiplexing runs in a single process flow.QUESTION 2
A program is 'Parallel' only if its concurrent flows...
...are managed by the kernel.
...execute simultaneously on separate processor cores.
...use shared memory for communication.
...are triggered by I/O events.
✅ Correct!
Parallelism is a subset of concurrency defined by physical simultaneity on hardware.❌ Incorrect
Logical concurrency can happen on a single core through time-slicing; parallelism requires multiple cores.QUESTION 3
What is a primary disadvantage of I/O Multiplexing compared to Threads?
High context-switch overhead.
Inability to exploit multi-core parallelism.
Difficulty in sharing global data.
Requirement for complex IPC mechanisms.
✅ Correct!
I/O multiplexing uses a single logical flow, meaning it cannot run tasks in parallel across multiple CPUs.❌ Incorrect
I/O multiplexing actually has lower overhead than threads and shares data easily since it's a single process.QUESTION 4
Why do modern windowing systems use concurrency for UI responsiveness?
To ensure memory safety.
To allow the interface to respond to user input while background tasks execute.
To prevent the kernel from reaping child processes.
To bypass the need for a file descriptor table.
✅ Correct!
Concurrency allows the main event loop to remain free for user interactions (clicks/resizing) while other flows handle computation.❌ Incorrect
Responsiveness is about overlapping the 'waiting' for human input with actual work.QUESTION 5
In the taxonomy of concurrency, which model models the application as a state machine?
Process-based
Thread-based
I/O Multiplexing
Sequential programming
✅ Correct!
I/O multiplexing often uses the 'select' or 'epoll' functions to transition between states based on file descriptor readiness.❌ Incorrect
Process and thread models usually follow a sequential-like flow within each independent entity.Deep Dive: Concurrency Architecture & Synchronization
Analysis of Process Management and Buffer Safety
Examine the mechanics of a concurrent server using process-based concurrency and the synchronization requirements of shared buffers in producer-consumer systems.
Q
Figure 12.5 demonstrates a concurrent server in which the parent process creates a child process to handle each new connection request. Trace the value of the reference counter for the associated file table for Figure 12.5.
Solution:
The reference counter for the connected file descriptor table entry evolves as follows:
1. Initial: The parent accepts a connection, creating
2. Fork: The parent calls
3. Parent Close: The parent calls
4. Child Termination: The child handles the request and exits (or calls
The reference counter for the connected file descriptor table entry evolves as follows:
1. Initial: The parent accepts a connection, creating
connfd. Reference count = 1.2. Fork: The parent calls
fork(). The child inherits the descriptor table. Reference count = 2.3. Parent Close: The parent calls
Close(connfd). Reference count = 1.4. Child Termination: The child handles the request and exits (or calls
Close). Reference count = 0, allowing the kernel to reclaim the socket.Q
Let $p$ denote producers, $c$ consumers, and $n$ the buffer size. Is the mutex semaphore in sbuf_insert/sbuf_remove necessary if (Scenario 1) $p=1, c=1$ and (Scenario 2) $p=1, c=10$?
Solution:
Scenario 1 ($p=1, c=1$): In a basic circular buffer where the producer only modifies the 'rear' and the consumer only modifies the 'front', a mutex is not strictly necessary for correctness, though often used for simplicity.
Scenario 2 ($p=1, c=10$): Yes, the mutex is mandatory. Because multiple consumers are competing to update the 'front' index and decrement the item count, a race condition would occur without mutual exclusion.
Scenario 1 ($p=1, c=1$): In a basic circular buffer where the producer only modifies the 'rear' and the consumer only modifies the 'front', a mutex is not strictly necessary for correctness, though often used for simplicity.
Scenario 2 ($p=1, c=10$): Yes, the mutex is mandatory. Because multiple consumers are competing to update the 'front' index and decrement the item count, a race condition would occur without mutual exclusion.
Q
If the parent process in Figure 12.5 failed to close its copy of the connected descriptor, what specific resource leak occurs?
Solution:
This results in a file descriptor leak. Even if the child process exits and closes its copy, the reference count in the kernel's file table never reaches zero because the parent (which runs forever) still holds a reference. Eventually, the server will hit its limit for open files and fail to accept new connections.
This results in a file descriptor leak. Even if the child process exits and closes its copy, the reference count in the kernel's file table never reaches zero because the parent (which runs forever) still holds a reference. Eventually, the server will hit its limit for open files and fail to accept new connections.